#pragma once

#include "NeuronInput.h"

#include <vector>

using std::vector;

enum NeuronActivationFunctionType
{
	identity,
	sigmoid
};

class Neuron : public NeuronInput
{
private:
	NeuronActivationFunctionType _activationFunctionType;

	vector<double> _weights;
	vector<NeuronInput*> _inputs;
	vector<double> _weightDerivatives;
	double _derivativeFactor;

	vector<Neuron*> _outputNeurons;
	vector<int> _outputNeuronInputIndexes;

	double CountActivate(double value);
	double CountActivateDerivative(double value);
	double CountWeightDerivative(unsigned int inputIndex);

public:
	Neuron(NeuronActivationFunctionType activationFunctionType);
	~Neuron();

	double CountOutputValue();

	void AddInput(NeuronInput* input, double weight);
	NeuronInput* GetInput(unsigned int index);
	double GetWeight(unsigned int index);
	void RemoveInput(unsigned int index);
	unsigned int NumInputs();

	void AddOutputNeuron(Neuron* neuron);

	bool CheckDerivatives(double expectedValue, double momentum);
	void Match(double learnFactor);
};
